(() => {
    // 多重泛型约束 & 交叉类型

    // 1.函数类型， 
    function extend<T, U>(first: T, second: U): T & U {
        let result = <T & U>{}
        for (let key in first) {
            (<any>result)[key] = first[key]
        }
        for (let key in second) {
            if (!second.hasOwnProperty(key)) {
                (<any>result)[key] = second[key]
            }
        }
        return result
    }
    class Person {
        constructor(public name: string) { }
    }
    interface A {
        log(): void
    }
    class B implements A {
        log() {
            console.log('打印');
        }
    }
    let resultObj = extend(new Person('名字'), new B())
    console.log(resultObj.name);
    resultObj.log()


    // 2.类类型
    interface J {
        name: string
        skill: string
    }
    interface K {
        price: number
    }

    class L<T extends J & K>{
        props: T
        constructor(public arg: T) {
            this.props = arg
        }

        info() {
            return {
                name: this.props.name,
                skill: this.props.skill,
                price: this.props.skill
            }
        }
    }
    let l = new L({
        name: '中世纪',
        skill: '文艺复兴',
        price: 100
    })
    l.info()


    // 类类型的联合类型
    interface AnimalInterface {
        height: number
        skill: string
    }
    interface PersonInterface {
        height: number
        vision: string
    }
    class Student<T extends AnimalInterface | PersonInterface> {
        features: T
        constructor(public args: T) {
            this.features = args
        }

        info() {
            return {
                height: this.features.height,
                // 报错，联合类型取交集，skil只存在AnimalInterface类型上
                // skill: this.features.skill
            }
        }
    }

    let student = new Student({
        height: 175,
        // 下面二者，至少要有其一
        skill: '吃饭',
        vision: '5.2'
    })
    console.log(student);


})()